// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.android.cloudapp;

import static com.android.cloudapp.CloudAppMsg.DATA_MSG_ID;

import android.os.RemoteException;

public class CloudAppCommunication extends ICloudAppCommunication.Stub {
    private static final String TAG = "CloudAppCommunication";
    private ICloudAppListener mCloudAppListener = null;
    private CloudAppDataChannelClient mDataChannel = null;
    private boolean mIsChannelConnected;
    private boolean mIsChannelStarted;

    private CloudAppDataChannelClient.CloudAppDataChannelMsgListener dataChannelMsgListener =
            new CloudAppDataChannelClient.CloudAppDataChannelMsgListener() {
                @Override
                public void onRecvMsg(byte[] data) throws RemoteException {
                    if (mCloudAppListener != null) {
                        mCloudAppListener.onCloudAppRecvData(data);
                    }
                }
            };
    private CloudAppDataChannelClient.CloudAppDataChannelDisconnectListener dataChannelDisconnectListener =
            new CloudAppDataChannelClient.CloudAppDataChannelDisconnectListener() {
                @Override
                public void onDisconnect() {
                    mIsChannelConnected = false;
                    new DataChannelConnectThread().start();
                }
            };

    public CloudAppCommunication() {
        mIsChannelConnected = false;
        mIsChannelStarted = false;
        mDataChannel = new CloudAppDataChannelClient();
        mDataChannel.setMsgListener(dataChannelMsgListener);
        mDataChannel.setDisconnectListener(dataChannelDisconnectListener);
        new DataChannelConnectThread().start();
    }

    @Override
    public int sendCloudAppData(byte[] data) throws RemoteException {
        if (data == null || data.length == 0) {
            CloudAppLog.e(TAG, "Param data is invalid.");
            return -1;
        }
        if (!mIsChannelConnected) {
            CloudAppLog.e(TAG, "Data channel unix socket not connected.");
            return -1;
        } else {
            return mDataChannel.sendMsg(data, DATA_MSG_ID);
        }
    }

    @Override
    public void setOnCloudAppRecvDataListener(ICloudAppListener listener) throws RemoteException {
        mCloudAppListener = listener;
    }

    private class DataChannelConnectThread extends Thread {
        @Override
        public void run() {
            mIsChannelConnected = false;
            if (mIsChannelStarted) {
                CloudAppLog.i(TAG, "Stop old data channel.");
                mDataChannel.close();
                mDataChannel.stop();
                mIsChannelStarted = false;
            }
            while (true) {
                if (mDataChannel.connect() == -1) {
                    CloudAppLog.i(TAG, " Connect failed.");
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    CloudAppLog.i(TAG, "Connect success.");
                    mDataChannel.start();
                    mIsChannelConnected = true;
                    mIsChannelStarted = true;
                    break;
                }
            }
        }
    }
}
